package fixpostattr

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

const limit = int64(30)
const (
	NUM256          = 256
	POST_COL_NUM    = NUM256
	POST_COL_FORMAT = "post_%d"
)
const (
	USER_COL_NUM   = NUM256
	USER_ID_FORMAT = "%d#u-%d#m_tias"

	USER_POST_OP_NUM    = NUM256
	USER_POST_OP_FORMAT = "user_post_op_%d"
	POST_ID_FORMAT      = "%d#p-%d#"

	RESOURCE_LOC_NUM    = NUM256
	RESOURCE_LOC_FOTMAT = "resource_loc_%d"
)

func FixPostAttr() {
	//client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://192.168.12.21:27017"))
	client, err := mongo.NewClient(options.Client().SetAuth(options.Credential{
		AuthMechanism: "SCRAM-SHA-1",
		AuthSource:    "admin",
		Username:      "bizsrv",
		Password:      "nG6KNRwxVGz1jNdQ",
	}).
		ApplyURI("mongodb://db-comics-post-2-0-0.xiaoniangao.cn:27077"))

	if err != nil {
		fmt.Println(err)
		return
	}
	ctx := context.Background()
	client.Connect(ctx)
	defer client.Disconnect(ctx)

	for i := 0; i < POST_COL_NUM; i++ {
		post := client.Database("tia_comics_post").Collection(fmt.Sprintf(POST_COL_FORMAT, i))
		postCOL(ctx, post, client)
	}

}

func postCOL(ctx context.Context, col *mongo.Collection, client *mongo.Client) {
	fmt.Println(col.Name())
	findOptions := options.Find()
	findOptions.SetLimit(limit)
	sum := int64(0)
	for {
		findOptions.SetSkip(sum)
		sum = sum + limit
		result, err := col.Find(nil, bson.M{}, findOptions)
		if err != nil {
			fmt.Println(err)
			panic(err)
		}
		if result.RemainingBatchLength() <= 0 {
			break
		}
		for result.Next(ctx) {
			//var group = make(map[string]interface{})
			var post = &Post{}
			result.Decode(post)
			if isNeed(post) {
				attr := 3 - post.Attribute

				op := getUserPostOp(ctx, client, post.UId, post.PId, attr)
				rl := getResourceLoc(ctx, client, post.UId, post.PId, attr)
				fmt.Printf("col:%v,postId:%v,aid:%#v,attr:%v,op.attr:%v,rl.attr:%v,createtime:%v\n", col.Name(), post.PId, post.AId, post.Attribute, op.Attribute, rl.Attribute, time.Unix(post.CreateTime/1000, 0))

				col.UpdateOne(ctx, bson.M{"_id": post.PId}, bson.M{"$set": bson.M{"attri": attr}})
			}
		}
		result.Close(ctx)
	}
}

func getUserPostOp(ctx context.Context, client *mongo.Client, uid string, pId string, attr int) *UserPostOp {
	var userId, mid int
	fmt.Sscanf(uid, USER_ID_FORMAT, &userId, &mid)
	userpostop := client.Database("tia_comics_user_post_op").Collection(fmt.Sprintf(USER_POST_OP_FORMAT, userId%USER_POST_OP_NUM))
	upo := &UserPostOp{}
	one := userpostop.FindOne(ctx, bson.M{"uid": uid, "pid": pId})
	one.Decode(upo)
	if upo.Attribute != 0 {
		userpostop.UpdateOne(ctx, bson.M{"pid": pId, "uid": uid}, bson.M{"$set": bson.M{"attri": attr}})
	}
	return upo
}

func getResourceLoc(ctx context.Context, client *mongo.Client, uid string, pId string, attr int) *ResourceLoc {
	var oid, pid int
	fmt.Sscanf(pId, POST_ID_FORMAT, &pid, &oid)
	userpostop := client.Database("tia_comics_resource_loc").Collection(fmt.Sprintf(RESOURCE_LOC_FOTMAT, pid%RESOURCE_LOC_NUM))
	upo := &ResourceLoc{}
	one := userpostop.FindOne(ctx, bson.M{"pid": pId})
	one.Decode(upo)
	if upo.Attribute != 0 {
		userpostop.UpdateMany(ctx, bson.M{"pid": pId}, bson.M{"$set": bson.M{"attri": attr}})
	}
	return upo
}

func isNeed(post *Post) bool {
	if post.AId == "" && post.Attribute == 2 {
		return true
	}
	if len(post.AId) >= 1 && post.Attribute == 1 {
		return true
	}
	return false
}
